﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Migrator.Entities;
using Migrator.Packets;
using System.Reflection;
using Migrator.Util;

namespace MigratorUI.UI
{
    public partial class NodePacketsForm : Form
    {
        public NodePacketsForm(Node node, List<IPPacket> packets, bool received)
        {
            InitializeComponent();

            this.node = node;
            this.packets = packets;
            this.received = received;

            InitPrimaryTable();

        }

        private void InitPrimaryTable()
        {
            this.Text = "Node " + node.MACAddress.ToString() + " " + (this.received ? "received" : "sent") + " packets";
            this.lvPacketsReceived.Columns[1].Text = (this.received ? "From" : "To");
            List<string> s = new List<string>();
            foreach (IPPacket ipPacket in packets)
            {
                string[] items = 
                {
                    ipPacket.GetType().Name,
                    ipPacket.SourceIP.ToString()
                };

                ListViewItem field = new ListViewItem(items);
                field.Tag = ipPacket;
                lvPacketsReceived.Items.Add(field);
            }
        }

        private void lvPacketsReceived_MouseClick(object sender, MouseEventArgs e)
        {
            lvPacketProperties.Clear();
            this.lvPacketProperties.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
            this.cProperty,
            this.cValue});

            var filter = new List<string>() { "Source", "Hops" };
            IPPacket ipPacket = (IPPacket)lvPacketsReceived.SelectedItems[0].Tag;
            Type baseObject = ipPacket.GetType();
            List<ListViewItem> listViewItems = new List<ListViewItem>();

            while (baseObject != typeof(object))
            {
                List<PropertyInfo> props = PropriedadesDoTipo(baseObject);
                foreach (PropertyInfo propertyInfo in props)
                {
                    if (filter.Contains(propertyInfo.Name))
                        continue;

                    var value = propertyInfo.GetValue(ipPacket, null);
                    string[] items;
                    if (value == null)
                    {
                        items = new string[] { propertyInfo.Name };
                    }
                    else
                    {
                        items = new string[]
                        {
                            propertyInfo.Name,
                        ((value is List<IPAddress>) ? ((List<IPAddress>) value).Aggregate("", (seed, element) => seed + element.ToString()+ " ") : value.ToString())
                        };
                    }

                    ListViewItem field = new ListViewItem(items);
                    lvPacketProperties.Items.Insert(0, field);                    
                }
                ListViewItem separator = lvPacketProperties.Items.Insert(0, new ListViewItem(baseObject.Name));
                separator.BackColor = Color.LightGray;
                baseObject = baseObject.BaseType;
            }
        }

        private List<PropertyInfo> PropriedadesDoTipo(Type type)
        {
            return new List<PropertyInfo>(type.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public));
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private Node node;
        private List<IPPacket> packets;

        private bool received;
    }
}
